package com.weike.yuanding.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.weike.yuanding.constant.UserVideoRelationEnum;
import com.weike.yuanding.core.domain.R;
import com.weike.yuanding.dto.user.UserFriendDTO;
import com.weike.yuanding.entity.UserVideoRelationEntity;
import com.weike.yuanding.entity.VideoMainEntity;
import com.weike.yuanding.entity.VideoReviewEntity;
import com.weike.yuanding.feign.user.UserService;
import com.weike.yuanding.mapper.UserVideoRelationMapper;
import com.weike.yuanding.mapper.VideoMainMapper;
import com.weike.yuanding.mapper.VideoReviewMapper;
import com.weike.yuanding.service.VideoService;
import com.weike.yuanding.strategy.VideoStrategy;
import com.weike.yuanding.strategy.VideoStrategyFactory;
import com.weike.yuanding.utils.BaseContext;
import com.weike.yuanding.vo.ReviewResVo;
import com.weike.yuanding.vo.VideoResVo;
import com.weike.yuanding.vo.VideoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @ClassName: VideoController
 * @Author: YuanDing
 * @Date: 2025/4/5 17:07
 * @Description: 视频相关的控制器类，处理视频推荐、观看、喜爱及评论等功能
 */
@RestController
@RequestMapping("video")
public class VideoController {

    @Autowired
    private VideoService videoService;

    @Autowired
    private VideoMainMapper videoMainMapper;

    @Autowired
    private VideoStrategyFactory videoStrategyFactory;

    @Autowired
    private VideoReviewMapper videoReviewMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private UserVideoRelationMapper userVideoRelationMapper;
    @Autowired
    private UserService userService;

    /**
     *
     * @param videoVo 输入参数，包含用户ID和视频ID
     * @return R 响应对象，表示操作结果
     */
    @PostMapping("/operate")
    public R operateVideo(@RequestBody VideoVo videoVo) {
        String userId = BaseContext.userId.get();
        if (videoVo.getType() != 4) {
            UserVideoRelationEntity userVideoRelationEntity = new UserVideoRelationEntity();
            userVideoRelationEntity.setVideoId(videoVo.getVideoId());
            userVideoRelationEntity.setUserId(userId);
            switch (videoVo.getType()) {
                case 1:  userVideoRelationEntity.setType(UserVideoRelationEnum.LIKE.getCode()); break;
                case 2:  userVideoRelationEntity.setType(UserVideoRelationEnum.SHOU_CANG.getCode()); break;
                case 3:  userVideoRelationEntity.setType(UserVideoRelationEnum.FEN_XIANG.getCode()); break;
            }

            userVideoRelationMapper.insert(userVideoRelationEntity);
        } else {

            UserFriendDTO userFriendDTO = new UserFriendDTO();
            userFriendDTO.setMyUserId(userId);
            userFriendDTO.setUserId(videoVo.getUserId());

            userService.guanzhu(userFriendDTO);
        }



        // 返回成功响应
        return R.ok();
    }

    /**
     *
     * @param videoVo 输入参数，包含用户ID和视频ID
     * @return R 响应对象，表示操作结果
     */
    @PostMapping("/operate/not")
    public R notOperateVideo(@RequestBody VideoVo videoVo) {
        String userId = BaseContext.userId.get();
        if (videoVo.getType() != 4) {
            int delete = userVideoRelationMapper.delete(new LambdaQueryWrapper<UserVideoRelationEntity>()
                    .eq(UserVideoRelationEntity::getVideoId, videoVo.getVideoId())
                    .eq(UserVideoRelationEntity::getUserId, userId)
                    .eq(UserVideoRelationEntity::getType, videoVo.getType()));
        } else {
            UserFriendDTO userFriendDTO = new UserFriendDTO();
            userFriendDTO.setMyUserId(userId);
            userFriendDTO.setUserId(videoVo.getUserId());
            userFriendDTO.setType("1");

            userService.guanzhu(userFriendDTO);
        }



        return R.ok();
    }


    /**
     * 添加用户观看过的视频到Redis中
     * @param videoVo 输入参数，包含用户ID和视频ID
     * @return R 响应对象，表示操作结果
     */
    @PostMapping("/addUserViewVideo")
    public R addUserViewVideo(@RequestBody VideoVo videoVo) {
        // 从VideoVo中获取用户ID和视频ID
        String userId = BaseContext.userId.get();
        String videoId = videoVo.getVideoId();

        // 验证输入参数是否为空
        if (userId == null || videoId == null) {
            return R.fail("用户ID或视频ID不能为空");
        }

        // 定义Redis中存储用户观看历史的键
        String viewedKey = "user:video:viewed:" + userId;

        // 将视频ID添加到用户的观看历史集合中
        redisTemplate.opsForSet().add(viewedKey, videoId);

        // 将用户ID添加到有观看记录的用户集合中，用于推荐算法
        redisTemplate.opsForSet().add("users:with:views", userId);

        // 返回成功响应
        return R.ok();
    }

    /**
     * 添加用户喜欢的视频到Redis中
     * @param videoVo 输入参数，包含用户ID和视频ID
     * @return R 响应对象，表示操作结果
     */
    @PostMapping("/addUserLikeVideo")
    public R addUserLikeVideo(@RequestBody VideoVo videoVo) {
        // 从VideoVo中获取用户ID和视频ID
        String userId = BaseContext.userId.get();
        String videoId = videoVo.getVideoId();

        // 验证输入参数是否为空
        if (userId == null || videoId == null) {
            return R.fail("用户ID或视频ID不能为空");
        }

        // 定义Redis中存储用户喜爱视频的键
        String likedKey = "user:video:liked:" + userId;

        // 将视频ID添加到用户的喜爱视频集合中
        redisTemplate.opsForSet().add(likedKey, videoId);

        // 返回成功响应
        return R.ok();
    }

    /**
     * 添加视频
     * @param videoMainEntity 视频实体，包含视频相关信息
     * @return R 响应对象，表示操作结果
     */
    @PostMapping
    public R addVideo(@RequestBody VideoMainEntity videoMainEntity) {
        // 从BaseContext获取当前用户ID，设置视频的创建者和关联用户
        videoMainEntity.setCreateUser(BaseContext.userId.get());
        videoMainEntity.setUserId(BaseContext.userId.get());

        // 设置初始曝光量为500
        videoMainEntity.setShowNumber(500);

        // 插入视频记录到数据库
        videoMainMapper.insert(videoMainEntity);
        return R.ok();
    }

    /**
     * 获取视频列表
     * @param videoVo 输入参数，包含视频类型等信息
     * @return R 响应对象，包含推荐的视频列表
     */
    @PostMapping("list")
    public R videoList(@RequestBody VideoVo videoVo) {
        // 使用策略模式根据type获取对应的视频推荐策略
        VideoStrategy strategy = videoStrategyFactory.getStrategy(videoVo.getType());
        if (strategy == null) {
            return R.fail("视频加载失败，错误的加载场景！");
        }
        List<VideoResVo> list = strategy.getVideoList(videoVo);
        return R.ok(list);
    }

    /**
     * 根据ID获取视频列表
     * @param videoVo 输入参数，包含视频ID等信息
     * @return R 响应对象，包含视频列表
     */
    @PostMapping("list/id")
    public R videoListById(@RequestBody VideoVo videoVo) {
        List<VideoResVo> list = videoService.listById(videoVo);
        return R.ok(list);
    }

    /**
     * 获取评论列表
     * @param videoVo 输入参数，包含视频ID等信息
     * @return R 响应对象，包含评论列表
     */
    @PostMapping("list/review")
    public R videoReviewList(@RequestBody VideoVo videoVo) {
        List<ReviewResVo> list = videoService.reviewList(videoVo);
        return R.ok(list);
    }

    /**
     * 发布评论
     * @param videoVo 输入参数，包含评论内容和视频ID
     * @return R 响应对象，表示操作结果
     */
    @PostMapping("/review")
    public R addReview(@RequestBody VideoVo videoVo) {
        VideoReviewEntity videoReviewEntity = new VideoReviewEntity();
        // 从BaseContext获取当前用户ID，设置评论的用户
        videoReviewEntity.setUserId(BaseContext.userId.get());
        videoReviewEntity.setReview(videoVo.getReviewContent());
        videoReviewEntity.setVideoId(videoVo.getVideoId());
        videoReviewMapper.insert(videoReviewEntity);
        return R.ok();
    }
}